using System.Collections.Generic;
using System.Linq;
using Castle.ActiveRecord;
using Castle.Components.Validator;
using NHibernate.Criterion;

namespace DecisionMaking.Domain
{
	[ActiveRecord]
	public class Candidate: ActiveRecordValidationBase<Candidate>
	{
		private IList<CandidateCueValue> _cueValues = new List<CandidateCueValue>();
		
	    [PrimaryKey(PrimaryKeyType.Native)]
	    public int Id {set; get;}	
		
		[BelongsTo(NotNull = true, UniqueKey = "uix_candidate_name")]
		public Environment Environment {set; get;}
		
		[Property(NotNull = true, UniqueKey = "uix_candidate_name"), ValidateLength(2, 50)]
		public string Name {set; get;}	
		
		[Property]
		public double IndependentVariableValue {set; get;}
		
		[HasMany(typeof(CandidateCueValue), Inverse = true, Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
		public IList<CandidateCueValue> CueValues
		{
			get {return _cueValues;}
			set {_cueValues = value;}
		}

        /// <summary>
        /// Returns the value for the specified cue or null if not found
        /// </summary>
        /// <param name="cue">
        /// A <see cref="Cue"/>
        /// </param>
        /// <returns></returns>
        public double? GetCueValue(Cue cue)
        {
            return (from c in CueValues where c.Cue.Equals(cue) select c.Value).Single();
        }

        /// <summary>
        /// Returns a list of Candidates from the specified Environment, fetching the cue values along with them 
        /// </summary>
        /// <param name="environmentId">
        /// A <see cref="System.Int32"/>
        /// </param>
        /// <returns></returns>
        public static IList<Candidate> FindByEnvironmentId(int environmentId)
        {
            DetachedCriteria criteria = DetachedCriteria.For(typeof(Candidate));

            criteria.CreateCriteria("Environment").Add(Restrictions.IdEq(environmentId));

            return FindAll(criteria);
        }

		public override bool Equals (object obj)
		{
			if (obj == null)
				return false;
			if (ReferenceEquals (this, obj))
				return true;
			if (obj.GetType () != typeof(Candidate))
				return false;
			Candidate other = (Candidate)obj;
			return Id == other.Id;
		}


		public override int GetHashCode ()
		{
			unchecked {
				return Id.GetHashCode ();
			}
		}

				
	}
}

